/*
 * (C) Copyright 2009
 * Sean Chiang, <n2i911@gmail.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 */

#ifndef OS_FALSE
#define OS_FALSE		0
#endif

#ifndef OS_TRUE
#define OS_TRUE 		1
#endif

.global OSCtxSw
OSCtxSw:
	/* save processor registers */
	stmfd	sp!, {r14}
	stmfd   sp!, {r14}
	stmfd   sp!, {r0-r12}
	mrs     r4, spsr
	stmfd   sp!, {r4}

	/* Save the current task's sp into the current task's TCB */
	ldr	r4, =OSTCBCur
	ldr	r5, [r4]
	str	sp, [r5, #0]

#if OS_TASK_SW_HOOK_EN > 0
	bl	OSTaskSwHook
#endif
	/* OSTCBCur = OSTCBHighRdy */
	ldr	r4, =OSTCBCur
	ldr	r5, =OSTCBHighRdy
	ldr	r6, [r5]
	str	r6, [r4]

	/* OSPrioCur = OSPrioHighRdy */
	ldr	r4, =OSPrioCur
	ldr	r5, =OSPrioHighRdy
	ldr	r6, [r5]
	str	r6, [r4]

	/* restore all processor registers, get the sp first*/
	ldr	r4, =OSTCBCur
	ldr	r5, [r4]
	ldr	sp, [r5, #0]

	ldmfd	sp!, {r4}
	msr	spsr_cxsf, r4

	ldmfd	sp!, {r0-r12, lr, pc}^

.global OSIntCtxSw
OSIntCtxSw:
#if OS_TASK_SW_HOOK_EN > 0
	bl	OSTaskSwHook
#endif

	/* OSTCBCur = OSTCBHighRdy */
	ldr	r4, =OSTCBCur
	ldr	r5, =OSTCBHighRdy
	ldr	r6, [r5]
	str	r6, [r4]

	/* OSPrioCur = OSPrioHighRdy */
	ldr	r4, =OSPrioCur
	ldr	r5, =OSPrioHighRdy
	ldr	r6, [r5]
	str	r6, [r4]

	/* restore all processor registers, get the sp first*/
	ldr	r4, =OSTCBCur
	ldr	r5, [r4]
	ldr	sp, [r5, #0]

	ldmfd	sp!, {r4}
	msr	spsr_cxsf, r4

	ldmfd	sp!, {r0-r12, lr, pc}^

.global OSStartHighRdy
OSStartHighRdy:
	/* Set OSRunning to TRUE*/
	ldr	r4, =OSRunning
	mov	r5, #OS_TRUE
	strb	r5, [r4]

	/* OSTCBStkPtr */
	ldr	r4, =OSTCBHighRdy
	ldr	r5, [r4]
	ldr	sp, [r5, #0]

	ldmfd	sp!, {r4}
	msr	spsr_cxsf, r4

	ldmfd	sp!, {r0-r12, lr, pc}^

.global OSTickISR
OSTickISR:
	mov	r4, lr
	bl	OSTimeTick
	bx	r4
